#include "IWatchdog.h"

bool IWatchdogClass::_enabled = false;

void IWatchdogClass::begin(uint32_t timeout, uint32_t window)
{
    set(timeout, window);

    _enabled = true;

    IWDG_Enable();
}

void IWatchdogClass::set(uint32_t timeout, uint32_t window)
{
    if ((isEnabled()) && (!IS_IWDG_TIMEOUT(timeout)))
    {
        return;
    }

    uint16_t div = 0;

    uint8_t prescaler = 0;
    uint32_t reload = 0;

    // Convert timeout to seconds
    float t_sec = (float)timeout / 1000000 * 32000UL;

    do
    {
        div = 4 << prescaler;
        prescaler++;
    } while ((t_sec / div) > 0xFFFUL);

    reload = (uint32_t)(t_sec / div) - 1;

    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

    IWDG_SetPrescaler(prescaler); //设置预分频器值
    IWDG_SetReload(reload);       //设置重装载寄存器的值
    IWDG_ReloadCounter();         //将重装载寄存器的值放入到计数器中
}

void IWatchdogClass::get(uint32_t *timeout, uint32_t *window)
{
    if (timeout != NULL)
    {
        uint32_t prescaler = 0;
        uint32_t reload = 0;
        float base = (1000000.0 / 32000UL);

        while(IWDG_GetFlagStatus(IWDG_FLAG_RVU) == SET);
        reload = IWDG->RLDR;
        while(IWDG_GetFlagStatus(IWDG_FLAG_PVU) == SET);
        prescaler = IWDG->PSCR;

        *timeout = (uint32_t)((4 << prescaler) * (reload + 1) * base);
    }
}

void IWatchdogClass::reload(void) 
{
    if (isEnabled()) {
        IWDG_ReloadCounter();
    }
}

IWatchdogClass IWatchdog = IWatchdogClass();